﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Collections.Specialized;

#pragma warning disable 1591
namespace SQLToolbox.Types.UnitTests
{
	[TestFixture]
	public class ScriptComparerUnitTests
	{

		[Test]
		public void TestCreate1()
		{
			StringCollection a = new StringCollection();
			a.Add("aaa\rbbb\nccc\r\nddd");

			Script result = new Script(a);

			Assert.AreEqual(result.Count, 1);
			Assert.AreEqual(result[0], "aaa\rbbb\nccc\r\nddd");
			Assert.AreEqual("aaa\rbbb\nccc\r\nddd", result.MergeForView());
		}



		[Test]
		public void TestCreate2()
		{
			StringCollection a = new StringCollection();
			a.Add("eee\rddd");
			a.Add("ttt");
			a.Add("aaa\rbbb\nccc\r\nddd");
			a.Add("sss");

			Script result = new Script(a);

			Assert.AreEqual(result.Count, 4);
			Assert.AreEqual(result[0], "eee\rddd");
			Assert.AreEqual(result[1], "ttt");
			Assert.AreEqual(result[2], "aaa\rbbb\nccc\r\nddd");
			Assert.AreEqual(result[3], "sss");
			Assert.AreEqual("eee\rddd\r\nGO\r\nttt\r\nGO\r\naaa\rbbb\nccc\r\nddd\r\nGO\r\nsss", result.MergeForView());
	
		}
		
		[Test]
		public void TestLeftAndRight()
		{
			Script a = new Script();
			a.Add("aaa");
			a.Add("aaa");
			a.Add("aaa");

			Script b = new Script();
			b.Add("saa");
			b.Add("asa");
			b.Add("aas");
			b.Add("sss");
			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			int i = 0;
			foreach (string s in cr.Left)
			{
				Assert.AreEqual(a[i], s);
				i++;
			}
			i = 0;
			foreach (string s in cr.Right)
			{
				Assert.AreEqual(b[i], s);
				i++;
			}
		}

		[Test]
		public void TestNulls()
		{
			Script a = new Script();
			a.Add("aaa");
			a.Add("aaa");
			a.Add("aaa");

			var cr = ScriptComparer.Compare(a, null);

			var expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", null, -1));
			expected.Add(new StringComparisonResult("aaa", null, -1));
			expected.Add(new StringComparisonResult("aaa", null, -1));
			int i = 0;
			foreach (var s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}

			cr = ScriptComparer.Compare(null, a);

			expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult(null, "aaa", -1));
			expected.Add(new StringComparisonResult(null, "aaa", -1));
			expected.Add(new StringComparisonResult(null, "aaa", -1));
			i = 0;
			foreach (var s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}

		}


		[Test]
		public void StringComaprisonEquals()
		{
			StringComparisonResult c = new StringComparisonResult("a", "b", 0);
			Assert.IsFalse(c.Equals(new object()));
			Assert.IsTrue(c.Equals(new StringComparisonResult("a", "b", 0)));
			Assert.IsTrue(c.Equals((object)new StringComparisonResult("a", "b", 0)));
			Assert.IsFalse(c.Equals(new StringComparisonResult("a", "c", 0)));
			Assert.AreEqual(0, StringComparer.Ordinal.Compare("Left: a;Right: b;DiffIndex: 0", c.ToString()));
		}

		[Test]
		public void SimpleComparison()
		{
			Script a = new Script();
			a.Add("aaa");
			a.Add("aaa");
			a.Add("aaa");

			Script b = new Script();
			b.Add("saa");
			b.Add("asa");
			b.Add("aas");
			b.Add("sss");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(4, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", "saa", 0));
			expected.Add(new StringComparisonResult("aaa", "asa", 1));
			expected.Add(new StringComparisonResult("aaa", "aas", 2));
			expected.Add(new StringComparisonResult(null, "sss", -1));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}

		[Test]
		public void SimpleComparison1()
		{
			Script a = new Script();
			a.Add("aaa");
			a.Add("aaa");


			Script b = new Script();
			b.Add("sss");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(2, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", "sss", 0));
			expected.Add(new StringComparisonResult("aaa", null, -1));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}

		[Test]
		public void SimpleComparison2()
		{
			Script a = new Script();
			a.Add("aaaa");


			Script b = new Script();
			b.Add("aaa");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(1, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaaa", "aaa", 3));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}

		[Test]
		public void SimpleComparison3()
		{
			Script a = new Script();
			a.Add("aaa");


			Script b = new Script();
			b.Add("aaaa");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(1, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", "aaaa", 3));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}

		[Test]
		public void SimpleComparisonEqual()
		{
			Script a = new Script();
			a.Add("aaa");


			Script b = new Script();
			b.Add("aaa");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(1, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsTrue(cr.AreEqual);
		}

		[Test]
		public void TestInsertedLinesRightSide()
		{
			Script a = new Script();
			a.Add("aaa");
			a.Add("aaa");
			a.Add("aaa");

			Script b = new Script();
			b.Add("aaa");
			b.Add("asa");
			b.Add("asa");
			b.Add("aaa");
			b.Add("aaa");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(5, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			expected.Add(new StringComparisonResult(null, "asa", -1));
			expected.Add(new StringComparisonResult(null, "asa", -1));
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}

		[Test]
		public void TestInsertedLinesLeftSide()
		{
			Script a = new Script();
			a.Add("aaa");
			a.Add("asa");
			a.Add("asa");
			a.Add("aaa");
			a.Add("aaa");

			Script b = new Script();
			b.Add("aaa");

			b.Add("aaa");
			b.Add("aaa");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(5, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			expected.Add(new StringComparisonResult("asa", null, -1));
			expected.Add(new StringComparisonResult("asa", null, -1));
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}

		[Test]
		public void TestInsertedLinesBothSides()
		{
			Script a = new Script();
			a.Add("aaa");
			a.Add("asa");
			a.Add("aaa");
			a.Add("aaa");

			Script b = new Script();
			b.Add("aaa");
			b.Add("aaa");
			b.Add("aka");
			b.Add("aaa");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(5, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			expected.Add(new StringComparisonResult("asa", null, -1));
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			expected.Add(new StringComparisonResult(null, "aka", -1));
			expected.Add(new StringComparisonResult("aaa", "aaa", -1));
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}

		[Test]
		public void HashCode()
		{
			Assert.AreNotEqual(new StringComparisonResult("aaa", "aaa", -1).GetHashCode(),
				new StringComparisonResult("aaa", "aaa", -1).GetHashCode());

		}
		[Test]
		public void TestForStringsWithDifferentLegnths()
		{
			Script a = new Script();
			a.Add("aa");
			a.Add("bbbbbb");
			a.Add("bbbbbb");
			a.Add("zz");

			Script b = new Script();
			b.Add("aavv");
			b.Add("bbsd");
			b.Add("bb");
			b.Add("zzzzzz");

			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(4, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aa", "aavv", 2));
			expected.Add(new StringComparisonResult("bbbbbb", "bbsd", 2));
			expected.Add(new StringComparisonResult("bbbbbb", "bb", 2));
			expected.Add(new StringComparisonResult("zz", "zzzzzz", 2));
			
			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}
		[Test]
		public void TestForStringsWithDifferentSizes()
		{
			Script a = new Script();
			a.Add("aa");
			a.Add("bb");
			

			Script b = new Script();
			b.Add("aa");
			b.Add("bb");
			b.Add("cc");
			b.Add("cc");
			b.Add("cc");
			b.Add("cc");
			ScriptComparisonResult cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(6, cr.Count);
			ScriptComparisonResult expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aa", "aa", -1));
			expected.Add(new StringComparisonResult("bb", "bb", -1));
			expected.Add(new StringComparisonResult(null, "cc", -1));
			expected.Add(new StringComparisonResult(null, "cc", -1));
			expected.Add(new StringComparisonResult(null, "cc", -1));
			expected.Add(new StringComparisonResult(null, "cc", -1));

			int i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);



			a = new Script();
			a.Add("aa");
			a.Add("bb");
			a.Add("cc");
			a.Add("cc");
			a.Add("cc");
			a.Add("cc");

			b = new Script();
			b.Add("aa");
			b.Add("bb");
		
			cr = ScriptComparer.Compare(a, b);
			Assert.AreEqual(6, cr.Count);
			expected = new ScriptComparisonResult();
			expected.Add(new StringComparisonResult("aa", "aa", -1));
			expected.Add(new StringComparisonResult("bb", "bb", -1));
			expected.Add(new StringComparisonResult("cc", null, -1));
			expected.Add(new StringComparisonResult("cc", null, -1));
			expected.Add(new StringComparisonResult("cc", null, -1));
			expected.Add(new StringComparisonResult("cc", null, -1));
			
			i = 0;
			foreach (StringComparisonResult s in cr)
			{
				Assert.AreEqual(expected[i++], s);
			}
			Assert.IsFalse(cr.AreEqual);
		}
	}
}
